// Copyright 2022 a.o.smith ALL Rights Reserved
package com.liuxinlong.modules.standard.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.liuxinlong.common.AosException;
import com.liuxinlong.common.ExcelImportCallBack;
import com.liuxinlong.common.ExcelImportService;
import com.liuxinlong.common.ImportResp;
import com.liuxinlong.common.RowError;
import com.liuxinlong.common.SnowFlake;
import com.liuxinlong.constant.ThreadLocalConstants;
import com.liuxinlong.constant.TimeFormatConstants;
import com.liuxinlong.enums.MessageContentTypeEnum;
import com.liuxinlong.enums.MessagePushBusinessEnum;
import com.liuxinlong.enums.ReturnCodes;
import com.liuxinlong.modules.dao.MessageDao;
import com.liuxinlong.modules.dao.StandardDao;
import com.liuxinlong.modules.dao.StandardNewsDao;
import com.liuxinlong.modules.entity.MessageConfiguration;
import com.liuxinlong.modules.entity.Standard;
import com.liuxinlong.modules.entity.StandardNews;
import com.liuxinlong.modules.entity.User;
import com.liuxinlong.modules.standard.dto.StandardNewsDto;
import com.liuxinlong.modules.standard.service.StandardNewsService;
import com.liuxinlong.utils.ObjectUtils;
import com.liuxinlong.utils.ThreadlocalUtils;
import com.liuxinlong.utils.TimeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 标准动态服务层实现类
 *
 * @author liuxinlong@hotwater.com.cn
 * @version 1.0.0
 * @since 2022年6月7日
 */
@Slf4j
@Service
public class StandardNewsServiceImpl implements StandardNewsService {

    @Autowired
    private StandardNewsDao standardNewsDao;

    @Autowired
    private ExcelImportService excelImportService;

    @Autowired
    private MessageDao messageDao;

    @Autowired
    private StandardDao standardDao;

    @Override
    public List<Map<String, Object>> pageStandardNewsInfo(Map<String, Object> queryParam) {
        int startNum = (int) queryParam.get("startNum");
        List<StandardNewsDto> originList = standardNewsDao.pageNewsList(queryParam);
        return completeResult(originList, startNum);
    }

    @Override
    public int getStandardNewsCount(Map<String, Object> queryParam) {
        return standardNewsDao.getNewsCount(queryParam);
    }

    @Transactional
    @Override
    public void addStandardNewsInfo(StandardNews standardNews,int syncMessage) {
        String id = SnowFlake.nextIdStr();
        standardNews.setId(id);
        standardNewsDao.insert(standardNews);
        User current = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        if (syncMessage == 1) {
            MessageConfiguration mc = new MessageConfiguration();
            mc.setId(SnowFlake.nextIdStr());
            mc.setBusinessType(MessagePushBusinessEnum.STANDARD.getValue());
            mc.setBusinessId(id);
            mc.setTitle("NA");
            mc.setCreateUser(current.getId());
            String currentTime = TimeUtils.getDate(TimeFormatConstants.YYYY_MM_DD_HH_MM_SS);
            mc.setCreateTime(currentTime);
            mc.setPushType(2);
            mc.setContent(generateContent(standardNews));
            mc.setShareUser(current.getName());
            mc.setTarget("3");
            messageDao.insert(mc);
        }
    }

    @Override
    @Transactional
    public void updateStandardNewsInfo(StandardNews standardNews,int syncMessage) {
        String id = standardNews.getId();
        if (StringUtils.isEmpty(id)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "参数异常，id不存在");
        }
        StandardNews oldInfo = standardNewsDao.selectById(id);
        if (ObjectUtils.isEmpty(oldInfo)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "参数异常，原标准动态不存在");
        }
        standardNewsDao.updateById(standardNews);
        User current = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        if (syncMessage == 1) {
            MessageConfiguration mc = new MessageConfiguration();
            mc.setId(SnowFlake.nextIdStr());
            mc.setBusinessType(MessagePushBusinessEnum.STANDARD.getValue());
            mc.setBusinessId(id);
            mc.setTitle("NA");
            mc.setCreateUser(current.getId());
            String currentTime = TimeUtils.getDate(TimeFormatConstants.YYYY_MM_DD_HH_MM_SS);
            mc.setCreateTime(currentTime);
            mc.setPushType(2);
            mc.setContentType(MessageContentTypeEnum.TEXT_CARD.getValue());
            mc.setContent(generateContent(standardNews));
            mc.setShareUser(current.getName());
            mc.setTarget("3");
            messageDao.insert(mc);
        }
    }

    @Override
    public void deleteStandardNewsInfo(String id) {
        standardNewsDao.deleteById(id);
    }

    /**
     * 补全数据
     *
     * @param originList 原始数据
     * @param startNum   起始数
     * @return 补全数据列表
     */
    private List<Map<String, Object>> completeResult(List<StandardNewsDto> originList, int startNum) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        if (ObjectUtil.isEmpty(originList)) {
            return resultList;
        }
        Date currentTime = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(TimeFormatConstants.YYYY_MM_DD_HH_MM_SS);
        int sort = startNum + 1;
        for (StandardNewsDto item : originList) {
            Map<String, Object> map = ObjectUtils.object2Map(item);
            map.put("sort", sort);
            try {
                Date operateTime = simpleDateFormat.parse(item.getOperateTime());
                String preposition = operateTime.before(currentTime) ? " 已在 " : " 将在 ";
                map.put("preposition", preposition);
            } catch (Exception e) {
                log.info("时间转换失败：{} ", item.getOperateTime());
            }
            resultList.add(map);
            sort++;
        }
        return resultList;
    }

    @Override
    public void exportStandardNewsInfo(String id, HttpServletResponse response) {
//        Map<String, Map<String, String>> hierarchyMap = hierarchyDao.getHierarchyMap();
//        Map<String, Map<String, String>> departmentMap = departmentDao.getDepartmentMap();
//        Map<String, Map<String, String>> classificationMap = classificationDao.getClassificationMap();
//        Map<String, Map<String, String>> fileMap = fileManageDao.getFileMap(FileBusinessTypeEnum.DESIGN_STANDARD_MASTER.getValue());
//        ExcelData data = new ExcelData();
//        data.setFileName("标准导出excel.xlsx");
//        List<StandardNews> standardList = standardNewsDao.getNewsList();
//        String[] head = {"标准编号", "标准名称", "标准类型", "作用层级", "部门", "回顾部门", "标准分类", "强制分类", "版本",
//                "保密等级", "适用范围", "参考标准", "状态", "发布时间", "主文件", "备注"};
//        data.setHead(head);
//        String[][] dataList = new String[standardList.size()][head.length];
//        int index = 0;
//        for (StandardNews ds : standardList) {
//            dataList[index][0] = ds.getStandardNewsSn();
//            dataList[index][1] = ds.getName();
//            dataList[index][2] = ds.getStandardNewsType() == 1 ? "设计标准" : ds.getStandardNewsType() == 2 ? "测试标准" : "设计&测试标准";
//            dataList[index][3] = StringUtils.isNotEmpty(ds.getHierarchy()) ?
//                    hierarchyMap.containsKey(ds.getHierarchy()) ? hierarchyMap.get(ds.getHierarchy()).get("name") : "" : "";
//            dataList[index][4] = StringUtils.isNotEmpty(ds.getDepartment()) ?
//                    departmentMap.containsKey(ds.getDepartment()) ? departmentMap.get(ds.getDepartment()).get("name") : "" : "";
//            dataList[index][5] = ds.getReviewDepartment();
////            dataList[index][5] = StringUtils.isNotEmpty(ds.getReviewDepartment()) ?
////                    departmentMap.containsKey(ds.getReviewDepartment()) ? departmentMap.get(ds.getReviewDepartment()).get("name") : "" : "";
//            dataList[index][6] = StringUtils.isNotEmpty(ds.getClassification()) ?
//                    classificationMap.containsKey(ds.getClassification()) ? classificationMap.get(ds.getClassification()).get("name") : "" : "";
//            dataList[index][7] = ds.getMandatory() == 1 ? "强制" : ds.getMandatory() == 2 ? "推荐" : "试行";
//            dataList[index][8] = ds.getVersion();
//            dataList[index][9] = ds.getSecurityLevel() == 1 ? "A" : "B";
//            dataList[index][10] = ds.getApplicability();
//            dataList[index][11] = ds.getReference();
//            dataList[index][12] = DesignStatusEnum.getNameByValue(ds.getStatus());
//            dataList[index][13] = ds.getPublishTime();
//            dataList[index][14] = StringUtils.isNotEmpty(ds.getMasterFile()) ?
//                    fileMap.containsKey(ds.getMasterFile()) ? fileMap.get(ds.getMasterFile()).get("name") : "" : "";
//            dataList[index][15] = ds.getRemark();
//            index++;
//        }
//        data.setData(Arrays.asList(dataList));
//        ExcelUtils.exportExcel(response, data);
    }

    @Override
    public ImportResp batchAddStandardNews(List<StandardNews> dataList) {
//        Map<String, Map<String, String>> standardSnMap = standardNewsDao.getStandardNewsSnMap();
//        User currentUser = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
//        List<Map> failedList = new ArrayList<>();
//        boolean insertSuccess;
//        int sort = 1;
//        for (StandardNews standard : dataList) {
//            String message = "";
//            if (standardSnMap.size() > 0 && standardSnMap.containsKey(standard.getStandardNewsSn())) {
//                message = "信息已存在";
//                insertSuccess = false;
//            } else {
//                String id = SnowFlake.nextIdStr();
//                standard.setId(id);
//                standard.setDepartment(currentUser.getDepartment());
//                standard.setCreateUser(currentUser.getId());
//                try {
//                    standardDao.insert(standard);
//                    insertSuccess = true;
//                } catch (Exception e) {
//                    insertSuccess = false;
//                    message = e.getMessage();
//                }
//            }
//            if (!insertSuccess) {
//                Map<String, Object> map = ObjectUtils.object2Map(standard);
//                map.put("sort", sort);
//                map.put("message", message);
//                sort++;
//                failedList.add(map);
//            }
//        }
        ImportResp resp = new ImportResp();
//        resp.setRetCode(failedList.size() > 0 ? ReturnCodes.HTTP_IMPORT_PART_FAIL.getRetCode() : ReturnCodes.HTTP_SUCCESS.getRetCode());
//        resp.setFailedList(failedList);
//        resp.setRetMessage(failedList.size() > 0 ? "导入设计标准信息部分成功" : "导入设计标准信息成功");
        return resp;
    }



    @Override
    public ImportResp importStandardNews(String fileName) {
        String filePath = fileName;
        return excelImportService.excelFile(filePath, 2, new ExcelImportCallBack() {
            @Override
            public Collection<RowError> checkRow(String[] record) {
                return checkRecordValid(record);
            }

            @Override
            public boolean persistRowToDb(String[] record) {
                StandardNews standard = covertToBean(record);
                return false;
//				try {
//					materialStandardNewsDao.insert(mocDetail);
//					return true;
//				} catch (Exception e) {
//					return false;
//				}
            }

            @Override
            public ImportResp partFailure(ImportResp resp) {
                resp.setRetCode(ReturnCodes.HTTP_SUCCESS.getRetCode());
                resp.setRetMessage("导入标准动态数据部分失败，总数=" + resp.getTotal() + ",失败总数=" + resp.getFailedTotal());
                return resp;
            }

            @Override
            public ImportResp allSuccess(ImportResp resp) {
                resp.setRetMessage("导入标准动态数据全部成功，总数=" + resp.getTotal());
                return resp;
            }

            @Override
            public List<Map> convertFailList(List<String[]> failRecords) {
                List<Map> list = new ArrayList<>();
                int sort = 1;
                for (String[] failRecord : failRecords) {
                    if (StringUtils.isEmpty(failRecord[3]) || StringUtils.equals(failRecord[3].trim(), "其他") || StringUtils.isEmpty(failRecord[9])) {
                        continue;
                    }
                    Map item = new HashMap();
                    item.put("sort", sort);
                    item.put("standardSn", failRecord[1]);
                    item.put("name", failRecord[2]);
                    item.put("standardType", StringUtils.equals(failRecord[3].trim(), "设计标准") ? 1 : StringUtils.equals(failRecord[3].trim(), "测试标准") ? 2 : 3);
                    item.put("reviewDepartment", StringUtils.isNotEmpty(failRecord[4]) ? failRecord[4].trim() : "");
                    item.put("hierarchy", failRecord[5]);
                    item.put("classification", failRecord[6]);
                    item.put("mandatory", StringUtils.equals(failRecord[7].trim(), "强制") ? 1 : StringUtils.equals(failRecord[7].trim(), "推荐") ? 2 : 3);
                    item.put("version", failRecord[8]);
                    item.put("securityLevel", StringUtils.equals(failRecord[9].trim(), "A") ? 1 : 2);
                    item.put("applicability", failRecord[10]);
                    list.add(item);
                    sort++;
                }
                return list;
            }

        });
    }

    /**
     * 转换数据为入库数据
     *
     * @param record 数据记录
     * @return 入库数据
     */
    private StandardNews covertToBean(String[] record) {
        StandardNews standardNews = new StandardNews();
//        standard.setStandardNewsSn(record[1].trim());
//        standard.setName(record[2].trim());
//        standard.setReviewDepartment(record[4].trim());
//        standard.setHierarchy(record[5].trim());
//        standard.setClassification(record[6].trim());
//        standard.setMandatory(2);
//        standard.setVersion(record[8].trim());
//        standard.setSecurityLevel(StringUtils.equals(record[9].trim(), "A") ? 1 : 2);
//        standard.setApplicability(record[10].trim());
        return standardNews;

    }

    /**
     * 校验参数合法性
     *
     * @param record 导入数据
     * @return 参数合法性
     */
    private Collection<RowError> checkRecordValid(String[] record) {
        List<RowError> rowErrors = new ArrayList<>();
        if (StringUtils.isEmpty(record[1].trim())) {
            addRowError("设计编号不能为空", rowErrors);
        } else {
            if (record[1].trim().length() > 20) {
                addRowError("设计编号长度不能超过20", rowErrors);
            }
        }
        if (StringUtils.isEmpty(record[2].trim())) {
            addRowError("设计名称不能为空", rowErrors);
        } else {
            if (record[2].trim().length() > 100) {
                addRowError("设计名称长度不能超过100", rowErrors);
            }
        }
        if (StringUtils.isEmpty(record[2].trim())) {
            addRowError("兼容性不能为空", rowErrors);
        } else {

            if (record[2].trim().length() > 100) {
                addRowError("兼容性字段非法", rowErrors);
            }
        }
        if (StringUtils.isEmpty(record[4].trim())) {
            addRowError("回顾部门不能为空", rowErrors);
        } else {
            if (record[4].trim().length() > 20) {
                addRowError("回顾部门长度不能超过20", rowErrors);
            }
        }
        return rowErrors;
    }

    /**
     * 添加错误行数据
     *
     * @param errorMessage 错误信息
     * @param rowErrors    错误行数据
     */
    private void addRowError(String errorMessage, List<RowError> rowErrors) {
        RowError rowError = new RowError(errorMessage);
        rowErrors.add(rowError);
    }

    /**
     * 生成标准动态信息内容
     *
     * @param standardNews 标准动态信息
     * @return 标准动态信息内容
     */
    private String generateContent(StandardNews standardNews){
        Date currentTime = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(TimeFormatConstants.YYYY_MM_DD_HH_MM_SS);
        StringBuffer content = new StringBuffer();
        String mainSn = standardNews.getMainSn();
        if (StringUtils.isNotEmpty(mainSn)) {
            Standard mainStandard = standardDao.selectById(mainSn);
            content.append("《");
            content.append(mainStandard.getStandardSn());
            content.append(" ");
            content.append(mainStandard.getName());
            content.append("》");
        }
        try {
            Date operateTime = simpleDateFormat.parse(standardNews.getOperateTime());
            String preposition = operateTime.before(currentTime) ? " 已在 " : " 将在 ";
            content.append(preposition);
            content.append(standardNews.getOperateTime(), 0, 10);
        } catch (Exception e) {
            log.info("时间转换失败：{} ", standardNews.getOperateTime());
        }
        content.append(standardNews.getOperateType() == 1 ? " 实施 " : standardNews.getOperateType() == 2 ? " 作废 " : "修订");
        String otherSn = standardNews.getOtherSn();
        if (StringUtils.isNotEmpty(otherSn)) {
            Standard otherStandard = standardDao.selectById(otherSn);
            content.append(standardNews.getOperateType() == 1 ? ",替换 " : standardNews.getOperateType() == 2 ? "，被 " : "");
            content.append("《");
            content.append(otherStandard.getStandardSn());
            content.append(" ");
            content.append(otherStandard.getName());
            content.append("》 ");
            if (standardNews.getOperateType() == 2) {
                content.append(" 替换 ");
            }
        }
        return content.toString();

    }
}
